home *** CD-ROM | disk | FTP | other *** search
/ Disc to the Future 2 / Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin / MAC / THINKC / 4_0 / GREPSTUF / GREPMAIN.C < prev    next >
C/C++ Source or Header  |  1986-10-31  |  8KB  |  367 lines

  1. /*
  2.     Grep-Wc
  3.  
  4.     Grep - Globally search for Regular Expressions and Print, i.e.,
  5.         g/r.e./p
  6.  
  7.     Wc - char, word, line/paragraph count
  8.  
  9.     Works on text or MacWrite files
  10.  
  11.     Special characters for patterns
  12.  
  13.     ^        Match beginning of line (if at beginning of pattern)
  14.     $        Match end of line (if at end of pattern)
  15.     .        Match any character
  16.     [..]    Match class of characters.  If first character following
  17.             the [ is ^, match all BUT the range of characters.  A range
  18.             of characters may be specified by separating them with a
  19.             dash, e.g., [a-z].  The dash itself may be included as a class
  20.             member by giving it as the first class char (e.g., [-a-z]).
  21.     *        Match any number of preceding things (if does not follow
  22.             *, ^ or $)
  23.  
  24.     Characters which have special meanings only in certain places in
  25.     the pattern do not have that meaning elsewhere.  Special meaning
  26.     may be turned off otherwise by escaping it with '\'.  The backslash
  27.     may be entered into a pattern by doubling it.
  28.     
  29.  
  30.     Paul DuBois
  31.     Wisconsin Regional Primate Research Center
  32.     1220 Capitol Court
  33.     University of Wisconsin-Madison
  34.     Madison, WI  53706  USA
  35.     
  36.     UUCP: {allegra, ihnp4, seismo}!uwvax!uwmacc!dubois
  37.     ARPA: dubois@rhesus.primate.wisc.edu
  38.           dubois@unix.macc.wisc.edu
  39.  
  40.     Version 1.0         12 March 1986  (written in Rascal)
  41.     Version 1.1        22 August 1986 (written in LightspeedC)
  42.         Fixed:
  43.         Menu goes away when window not active.
  44.         Can be selected from Apple menu while open w/o crashing.
  45.         Doesn't pass handle-ized rects to ToolBox routines.
  46.         Upper limits on window sizing are machine sensitive.
  47.         Always uses System file Get/PutFile dialogs (e.g., in MacWrite).
  48. */
  49.  
  50.  
  51.  
  52. # include    "Grep.h"
  53. # include    <DeviceMgr.h>
  54. # include    <EventMgr.h>
  55. # include    <MenuMgr.h>
  56. # include    <FileMgr.h>
  57.  
  58.  
  59.  
  60. /*  global variables  */
  61.  
  62. Boolean        isOpen = false;        /* true if DA already open */
  63. WindowPtr    theWind;
  64. DCtlPtr        dce;
  65. int            dCtlRefNum;
  66. TEHandle    teHand;
  67. MenuHandle    theMenu;
  68. Rect        growRect;
  69. int            resBase;            /* base DA resource number */
  70. Boolean        fileOpen = false;    /* whether output file is open */
  71. int            outFile;            /* output file reference number */
  72.  
  73. /*
  74.     search options
  75. */
  76.  
  77. Boolean        prtMatches = true;    /* true: print lines w/pattern */
  78. Boolean        prtLineNum = false;    /* print line numbers if true */
  79. Boolean        ignoreCase = false;    /* ignore letter case if true */
  80.  
  81. /*
  82.     other information about search
  83. */
  84.  
  85. Boolean        grepping;        /* true if currently searching */
  86. Boolean        paused;            /* true if pause button was hit */
  87. Boolean        havePat = true;    /* whether have good pattern or not */
  88.  
  89. ControlHandle    pauseCtl;
  90. ControlHandle    cancelCtl;
  91.  
  92.  
  93.  
  94. Alarm (mesg)
  95. StringPtr    mesg;
  96. {
  97.     ParamText (mesg, "\p", "\p", "\p");
  98.     (void) Alert (resBase + alarmBox, nil);
  99. }
  100.  
  101.  
  102.  
  103. /*
  104.     Redraw the window.  It is assumed that the port is set correctly.
  105.     The ValidRect is done because sometimes this is called before any
  106.     update event is obtained.  The ValidRect cancels any that might be
  107.     pending, preventing two redraws.
  108. */
  109.  
  110. Update ()
  111. {
  112. Rect    r;
  113.  
  114.     DrawControls (theWind);
  115.     MoveTo (0, 24);
  116.     LineTo (30000, 24);
  117.     r = (**teHand).viewRect;
  118.     TEUpdate (&r, teHand);
  119.     ValidRect (&theWind->portRect);
  120. }
  121.  
  122.  
  123. FiddleMenu (activate)
  124. Boolean    activate;
  125.  
  126. {
  127.     if (activate)
  128.         InsertMenu (theMenu, 0);
  129.     else
  130.         DeleteMenu (dCtlRefNum);
  131.  
  132.     DrawMenuBar ();
  133. }
  134.  
  135.  
  136. main(p, d, n)
  137. register cntrlParam    *p;    /*  ==> parameter block  */
  138. register DCtlPtr    d;    /*  ==> device control entry  */
  139. int                    n;    /*  entry point selector  */
  140.  
  141. {
  142. Point            thePt;
  143. Rect            r;
  144. EventRecord        *theEvent;
  145. ControlHandle    ctl;
  146.  
  147.     dCtlRefNum = (dce = d)->dCtlRefNum;
  148.  
  149.     /*  check to make sure data area was allocated  */
  150.         
  151.     if (d->dCtlStorage == 0)
  152.     {
  153.         if (n == 0)                        /*  open  */
  154.             CloseDriver(dCtlRefNum);
  155.     }
  156.     else switch (n)    /*  dispatch  */
  157.     {
  158.  
  159.     case 0:        /*  open  */
  160.  
  161.         /*
  162.             Need to set these values each time, because the OS resets
  163.             them before every call...
  164.         */
  165.  
  166.         d->dCtlFlags |= dNeedLock | dNeedTime | dNeedGoodBye;
  167.         d->dCtlDelay = 0;
  168.         d->dCtlEMask = updateEvt | activateEvt | mouseDown ;
  169.         d->dCtlMenu = dCtlRefNum;
  170.  
  171. /*
  172.     Check to see whether already open or not.  If not, set up window,
  173.     window growing limits, etc.  The SelectWindow is for the case where
  174.     the DA is already open but hidden behind some other window.
  175.     Selecting Grep from the DA menu when already open simply has the
  176.     effect of bringing it to the front.
  177. */
  178.     
  179.         if (!isOpen)
  180.         {
  181.             isOpen = true;
  182.  
  183.             theMenu = NewMenu (dCtlRefNum, "\pGrep-Wc");
  184.             AppendMenu (theMenu, "\pAbout Grep-Wc;(-;Count...");
  185.             AppendMenu (theMenu, "\pSearch...;Set Pattern...;Save Output...");
  186.  
  187.             GetWMgrPort (&theWind);
  188.             growRect = theWind->portRect;
  189.             growRect.left = 180;
  190.             growRect.top = 60;
  191.             SetRect (&r, 25, 80, 490, 320);
  192.             theWind = NewWindow (nil, &r, "\pGrep-Wc", true,
  193.                                     documentProc, -1L, true, 0L);
  194.             ((WindowPeek) theWind)->windowKind = dCtlRefNum;
  195.             SetPort (theWind);
  196.             TextFont (monaco);
  197.             TextSize (9);
  198.  
  199.             /*  Create TERec and build controls  */
  200.  
  201.             OffsetRect (&r, -r.left, -r.top);    /* move to (0, 0) */
  202.             r.top += 25;            /* leave room for buttons */
  203.             r.left += 6;
  204.             teHand = TENew (&r, &r);
  205.             (**teHand).crOnly = -1; /* no word wrap */
  206.  
  207.             SetRect (&r, 5, 2, 85, 22);
  208.             pauseCtl =
  209.                 NewControl (theWind, &r, "\pPause", true,
  210.                                 0, 0, 0, pushButProc, nil);
  211.             OffsetRect (&r, 90, 0);
  212.             cancelCtl =
  213.                 NewControl (theWind, &r, "\pCancel", true,
  214.                                 0, 0, 0, pushButProc, nil);
  215.         
  216.             GrepState (255);    /* set grepping false, inactivate buttons */
  217.  
  218.             /* determine base resource number */
  219.  
  220.             resBase =  0xc000 + (~dCtlRefNum << 5);
  221.  
  222.         }
  223.  
  224.         SelectWindow (theWind);
  225.  
  226.         break;
  227.  
  228.     case 2:        /*  control  */
  229.  
  230.         SetPort (theWind);
  231.         switch (p->csCode)
  232.         {
  233.  
  234.         case accEvent:    /* need glasses for next statement */
  235.  
  236.             theEvent = (EventRecord *) * (long *) &p->csParam;
  237.             switch (theEvent->what)
  238.             {
  239.  
  240.             case activateEvt:
  241.  
  242.                 /*
  243.                     Set up or destroy menu, depending
  244.                     on activate type.
  245.                 */
  246.                 FiddleMenu (theEvent->modifiers & activeFlag);
  247.                 break;
  248.             
  249.             case updateEvt:
  250.             
  251.                 BeginUpdate (theWind);
  252.                 Update ();
  253.                 EndUpdate (theWind);
  254.                 break;
  255.  
  256.             case mouseDown:
  257.  
  258. /*
  259.     Check mouse click and whether it's a window grow event.
  260.     Must do the test explicitly, since DA's don't get told about
  261.     clicks in the inGrow region.
  262. */
  263.                 thePt = theEvent->where;
  264.                 GlobalToLocal (&thePt);
  265.                 r = theWind->portRect;
  266.                 r.left = r.right - 15;
  267.                 r.top = r.bottom - 15;
  268.                 if (PtInRect (thePt, &r))
  269.                 {
  270.                     LocalToGlobal (&thePt);
  271.                     * (long *) &thePt = GrowWindow (theWind, thePt, &growRect);
  272.                     SizeWindow (theWind, thePt.h, thePt.v, true);
  273.                     r = theWind->portRect;
  274.                     ClipRect (&r);
  275.                     /*InvalRect (&r);        /* force update event */
  276.                 /*
  277.                     Reset the text viewRect.  It's
  278.                     not necessary to reset the destRect,
  279.                     since only the top and left are
  280.                     used, and they haven't changed.
  281.                 */
  282.                     r.top += 25;
  283.                     r.left += 6;
  284.                     (**teHand).viewRect = r;
  285.                 }
  286.                 else if (FindControl (thePt, theWind, &ctl))
  287.                 {
  288.                     if (TrackControl (ctl, thePt, nil))
  289.                     {
  290.                         if (ctl == cancelCtl)
  291.                         {
  292.                             StopGrep ();
  293.                         }
  294.                         else if (ctl == pauseCtl)
  295.                         {
  296.                             if (paused)
  297.                                 SetCTitle (pauseCtl, "\pPause");
  298.                             else
  299.                                 SetCTitle (pauseCtl, "\pResume");
  300.                             paused = !paused;
  301.                         }
  302.                     }
  303.                 }
  304.                 break;
  305.             }
  306.             break;
  307.  
  308.         case accMenu:
  309.  
  310.             switch (* (int *) ((Ptr) &p->csParam + 2))
  311.             {
  312.                 case about:
  313.                     (void) Alert (resBase + aboutBox, nil);
  314.                     break;
  315.  
  316.                 case count:
  317.                     StopGrep ();    /* terminate any ongoing grep operation */
  318.                     if (GetStream ())
  319.                         Wc ();
  320.                     break;
  321.  
  322.                 case search:
  323.                     StartGrep ();
  324.                     break;
  325.  
  326.                 case setPattern:
  327.                     GetGrepPat ();
  328.                     break;
  329.  
  330.                 case saveOutput:
  331.                     FileOutput ();
  332.                     break;
  333.             }
  334.  
  335.             HiliteMenu (0);
  336.             break;
  337.  
  338.         case accRun:
  339.             if ((theWind == FrontWindow ()) && grepping)
  340.                 GrepLine ();
  341.             break;
  342.  
  343.         case goodBye:
  344.             CloseStream ();                 /* close any open input file */
  345.             if (fileOpen)                /* close output file if open */
  346.                 FileOutput ();
  347.             break;
  348.  
  349.         }
  350.         break;
  351.  
  352.     case 4:        /*  close  */
  353.         CloseStream ();                 /* close any open input file */
  354.         if (fileOpen)                /* close output file if open */
  355.             FileOutput ();
  356.         FiddleMenu (false);
  357.         DisposeMenu (theMenu);        /* toss menu */
  358.         TEDispose (teHand);             /* toss text record */
  359.         DisposeWindow (theWind);    /* get rid of window and controls */
  360.         break;
  361.     }
  362.     
  363.     /*  done  */
  364.     
  365.     return (0);
  366. }
  367.